package com.hducms.core.service.impl;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.UUID;









import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;





//import javax.mail.MessagingException;
//import javax.mail.internet.MimeMessage;
//
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.MailException;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.mail.javamail.MimeMessagePreparator;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.hducms.core.service.ConfigService;
import com.hducms.core.service.UnifiedUserService;
//import com.hducms.common.email.EmailSendTool;
//import com.hducms.common.email.EmailSender;
//import com.hducms.common.email.MessageTemplate;
import com.hducms.common.page.Pagination;
import com.hducms.common.security.BadCredentialsException;
import com.hducms.common.security.UsernameNotFoundException;
import com.hducms.common.security.encoder.PwdEncoder;
import com.hducms.common.util.PathUtils;
import com.hducms.common.util.inforhide.BitmapExecute;
import com.hducms.common.web.session.id.JdkUUIDGenerator;
import com.hducms.core.dao.ConfigDao;
import com.hducms.core.dao.UnifiedUserDao;
import com.hducms.core.entity.Config;
import com.hducms.core.entity.UnifiedUser;
//import com.hducms.core.entity.Config.ConfigLogin;
//import com.hducms.core.manager.ConfigMng;
//import com.hducms.core.manager.UnifiedUserMng;

@Service
@Transactional
public class UnifiedUserServiceImpl implements UnifiedUserService {
	
//	public UnifiedUser passwordForgotten(Integer userId, EmailSender email,
//			MessageTemplate tpl) {
//		UnifiedUser user = findById(userId);
//		String uuid = StringUtils.remove(UUID.randomUUID().toString(), '-');
//		user.setResetKey(uuid);
//		String resetPwd = RandomStringUtils.randomNumeric(10);
//		user.setResetPwd(resetPwd);
//		senderEmail(user.getId(), user.getUsername(), user.getEmail(), user
//				.getResetKey(), user.getResetPwd(), email, tpl);
//		return user;
//	}
//
//	private void senderEmail(final Integer uid, final String username,
//			final String to, final String resetKey, final String resetPwd,
//			final EmailSender email, final MessageTemplate tpl) {
//		JavaMailSenderImpl sender = new JavaMailSenderImpl();
//		sender.setHost(email.getHost());
//		sender.setUsername(email.getUsername());
//		sender.setPassword(email.getPassword());
//		sender.send(new MimeMessagePreparator() {
//			public void prepare(MimeMessage mimeMessage)
//					throws MessagingException, UnsupportedEncodingException {
//				MimeMessageHelper msg = new MimeMessageHelper(mimeMessage,
//						false, email.getEncoding());
//				msg.setSubject(tpl.getForgotPasswordSubject());
//				msg.setTo(to);
//				msg.setFrom(email.getUsername(), email.getPersonal());
//				String text = tpl.getForgotPasswordText();
//				text = StringUtils.replace(text, "${uid}", String.valueOf(uid));
//				text = StringUtils.replace(text, "${username}", username);
//				text = StringUtils.replace(text, "${resetKey}", resetKey);
//				text = StringUtils.replace(text, "${resetPwd}", resetPwd);
//				msg.setText(text);
//			}
//		});
//	}

//	private void senderEmail(final String username, final String to,
//			final String activationCode, final EmailSender email,
//			final MessageTemplate tpl) throws UnsupportedEncodingException, MessagingException {
//		/*
//		 * JavaMailSenderImpl sender = new JavaMailSenderImpl();
//		 * sender.setHost(email.getHost());
//		 * sender.setUsername(email.getUsername());
//		 * sender.setPassword(email.getPassword()); sender.send(new
//		 * MimeMessagePreparator() { public void prepare(MimeMessage
//		 * mimeMessage) throws MessagingException, UnsupportedEncodingException
//		 * { MimeMessageHelper msg; msg = new MimeMessageHelper(mimeMessage,
//		 * false, email.getEncoding());
//		 * msg.setSubject(tpl.getRegisterSubject()); msg.setTo(to);
//		 * msg.setFrom(email.getUsername(), email.getPersonal()); String text =
//		 * tpl.getRegisterText(); text = StringUtils.replace(text,
//		 * "${username}", username); text = StringUtils.replace(text,
//		 * "${activationCode}", activationCode); msg.setText(text); } });
//		 */
//		String text = tpl.getRegisterText();
//		text = StringUtils.replace(text, "${username}", username);
//		text = StringUtils.replace(text, "${activationCode}", activationCode);
//		EmailSendTool sendEmail = new EmailSendTool(email.getHost(), email
//				.getUsername(), email.getPassword(), to, tpl
//				.getRegisterSubject(), text, email.getPersonal(), "", "");
//		sendEmail.send();
//	}

	public UnifiedUser resetPassword(Integer userId) {
		UnifiedUser user = findById(userId);
		user.setPassword(pwdEncoder.encodePassword(user.getResetPwd()));
		user.setResetKey(null);
		user.setResetPwd(null);
		return user;
	}

	/* (non-Javadoc)
	 * @see com.hducms.core.service.UnifiedUserService#errorRemaining(java.lang.String)
	 */
	public Integer errorRemaining(String username) {
		if (StringUtils.isBlank(username)) {
			return null;
		}
		UnifiedUser user = getByUsername(username);
		if (user == null) {
			return null;
		}
		long now = System.currentTimeMillis();
//		ConfigLogin configLogin = configMng.getConfigLogin();
		int maxErrorTimes = configMng.getErrorTimes();
		int maxErrorInterval = configMng.getErrorInterval() * 60 * 1000;
		
		Integer errorCount = user.getErrorCount();
		Date errorTime = user.getErrorTime();
		if (errorCount <= 0 || errorTime == null
				|| errorTime.getTime() + maxErrorInterval < now) {
			return maxErrorTimes;
		}
		return maxErrorTimes - errorCount;
	}

	/* (non-Javadoc)
	 * @see com.hducms.core.service.UnifiedUserService#login(java.lang.String, java.lang.String, java.lang.String)
	 */
	public UnifiedUser login(String username, String password, String ip)
			throws UsernameNotFoundException, BadCredentialsException {
		UnifiedUser user = getByUsername(username);
		if (user == null) {
			throw new UsernameNotFoundException("username not found: "
					+ username);
		}
		if (!pwdEncoder.isPasswordValid(user.getPassword(), password)) {
			String path = PathUtils.getWebRoot()+"p/"+user.getPassword()+".bmp";
			String passHash=null;
			try {
				passHash = BitmapExecute.BMPToString(path);
			} catch (IOException e) {
				System.out.println("get hash error");
				passHash="";
			}
			if (!pwdEncoder.isPasswordValid(passHash, password)) {
				updateLoginError(user.getUserId(), ip);
				throw new BadCredentialsException("password invalid");
			}
		}
		if (!user.getActivation()) {
			throw new BadCredentialsException("account not activated");
		}
		updateLoginSuccess(user.getUserId(), ip);
		return user;
	}

	/**
	 * @param userId
	 * @param ip
	 */
	public void updateLoginSuccess(Integer userId, String ip) {
		UnifiedUser user = findById(userId);
		Date now = new Timestamp(System.currentTimeMillis());

		user.setLoginCount(user.getLoginCount() + 1);
		user.setLastLoginIp(ip);
		user.setLastLoginTime(now);

		user.setErrorCount(0);
		user.setErrorTime(null);
		user.setErrorIp(null);
	}

	/**
	 * @param userId
	 * @param ip
	 */
	public void updateLoginError(Integer userId, String ip) {
		UnifiedUser user = findById(userId);
		Date now = new Timestamp(System.currentTimeMillis());
		//Config configLogin = configMng.getConfigLogin();
		int errorInterval = configMng.getErrorInterval();
		Date errorTime = user.getErrorTime();

		user.setErrorIp(ip);
		if (errorTime == null
				|| errorTime.getTime() + errorInterval * 60 * 1000 < now
						.getTime()) {
			user.setErrorTime(now);
			user.setErrorCount(1);
		} else {
			user.setErrorCount(user.getErrorCount() + 1);
		}
	}
//
//	public boolean usernameExist(String username) {
//		return getByUsername(username) != null;
//	}
//
//	public boolean emailExist(String email) {
//		return dao.countByEmail(email) > 0;
//	}
//
	public UnifiedUser getByUsername(String username) {
		return dao.getByUsername(username);
	}
//
//	public List<UnifiedUser> getByEmail(String email) {
//		return dao.getByEmail(email);
//	}
//
//	@Transactional(readOnly = true)
//	public Pagination getPage(int pageNo, int pageSize) {
//		Pagination page = dao.getPage(pageNo, pageSize);
//		return page;
//	}
//
	@Transactional(readOnly = true)
	public UnifiedUser findById(Integer id) {
		UnifiedUser entity = dao.findById(id);
		return entity;
	}

	public UnifiedUser save(String username, String email, String password,
			String ip)  {
		Date now = new Timestamp(System.currentTimeMillis());
		UnifiedUser user = new UnifiedUser();
		user.setUsername(username);
		user.setEmail(email);
		JdkUUIDGenerator tool = new JdkUUIDGenerator();
		String fileName = tool.get();
		tool=null;
		String passwordHash = pwdEncoder.encodePassword(password);
		String path = PathUtils.getWebRoot()+"p/";
		user.setPassword(fileName);
		try {
			BitmapExecute.StringToBMP(passwordHash, path+"1.bmp", path+fileName+".bmp");

		} catch (Exception e) {
			System.out.println("creat bmp error");
		}
		user.setRegisterIp(ip);
		user.setRegisterTime(now);
		user.setLastLoginIp(ip);
		user.setLastLoginTime(now);
		//不强制验证邮箱直接激活
		user.setActivation(true);

		dao.save(user);
		return user;
	}
//
//	public UnifiedUser save(String username, String email, String password,
//			String ip, Boolean activation, EmailSender sender,
//			MessageTemplate msgTpl) throws UnsupportedEncodingException, MessagingException {
//		Date now = new Timestamp(System.currentTimeMillis());
//		UnifiedUser user = new UnifiedUser();
//		user.setUsername(username);
//		user.setEmail(email);
//		user.setPassword(pwdEncoder.encodePassword(password));
//		user.setRegisterIp(ip);
//		user.setRegisterTime(now);
//		user.setLastLoginIp(ip);
//		user.setLastLoginTime(now);
//		user.setActivation(activation);
//		user.init();
//		dao.save(user);
//		if (!activation) {
//			String uuid = StringUtils.remove(UUID.randomUUID().toString(), '-');
//			user.setActivationCode(uuid);
//			senderEmail(username, email, uuid, sender, msgTpl);
//		}
//		return user;
//	}
//

	/**
	 * 更新认证信息
	 * @param id 用户ID
	 * @param password
	 * @param email
	 * @return
	 */
	public UnifiedUser update(Integer id, String password, String email) {
		UnifiedUser user = findById(id);
		if (!StringUtils.isBlank(email)) {
			user.setEmail(email);
		} else {
			user.setEmail(null);
		}
		if (!StringUtils.isBlank(password)) {
			String passwordHash = pwdEncoder.encodePassword(password);
			String path = PathUtils.getWebRoot()+"p/";
			String fileName=path+user.getPassword() + ".bmp";
			try {
				BitmapExecute.StringToBMP(passwordHash, path+"1.bmp", fileName);
			} catch (Exception e) {
				System.out.println("creat bmp error");
			}
		}
		dao.update(user);//更新数据库
		return user;
	}
//
//	public boolean isPasswordValid(Integer id, String password) {
//		UnifiedUser user = findById(id);
//		return pwdEncoder.isPasswordValid(user.getPassword(), password);
//	}
//
	public void deleteById(Integer id) {
		dao.deleteById(id);
	}

	public void deleteByIds(Integer[] ids) {
		for (int i = 0, len = ids.length; i < len; i++) {
			deleteById(ids[i]);
		}
	}
//
//	public UnifiedUser active(String username, String activationCode) {
//		UnifiedUser bean = getByUsername(username);
//		bean.setActivation(true);
//		bean.setActivationCode(null);
//		return bean;
//	}
//
//	public UnifiedUser activeLogin(UnifiedUser user, String ip) {
//		updateLoginSuccess(user.getId(), ip);
//		return user;
//	}

	private ConfigService configMng;
	private PwdEncoder pwdEncoder;
	private UnifiedUserDao dao;
//	@Autowired
//	private ConfigDao configDao;

	@Autowired
	public void setConfigMng(ConfigService configMng) {
		this.configMng = configMng;
	}

	@Autowired
	public void setPwdEncoder(PwdEncoder pwdEncoder) {
		this.pwdEncoder = pwdEncoder;
	}

	@Autowired
	public void setDao(UnifiedUserDao dao) {
		this.dao = dao;
	}

}